﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NavigationGroup.cs" company="Anton Frattaroli">
//   Copyright (c) Anton Frattaroli. All rights reserved.
// </copyright>
// <summary>
//   Defines the NavigationGroup class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Lidocaine
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;

    /// <summary>
    /// Defines the NavigationGroup class.
    /// </summary>
    public class NavigationGroup
    {
        #region Fields
        /// <summary>
        /// The name of the navigation group.
        /// </summary>
        private string name;

        /// <summary>
        /// Stores the area this navigation group is intended for (top or left).
        /// </summary>
        private NavigationGroupArea area;

        /// <summary>
        /// Stores the items of this navigation group.
        /// </summary>
        private IList<NavigationItem> items;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the NavigationGroup class.
        /// </summary>
        public NavigationGroup()
        {
        }

        /// <summary>
        /// Initializes a new instance of the NavigationGroup class. Only intended for loading existing navigation groups.
        /// </summary>
        /// <param name="name">The name of the navigation group.</param>
        /// <param name="area">The intended location of the navigation group.</param>
        public NavigationGroup(string name, NavigationGroupArea area)
        {
            using (SqlConnection conn = new SqlConnection(Environmental.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetNavGroup", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@NavItemGroup", name);
                    cmd.Parameters.AddWithValue("@NavItemArea", area);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            this.name = name;
                            this.area = area;
                            List<NavigationItem> navItems = new List<NavigationItem>();
                            while (rdr.Read())
                            {
                                navItems.Add(new NavigationItem(rdr["NavItemText"].ToString(), rdr["NavItemLink"].ToString(), Convert.ToInt32(rdr["NavItemOrder"], CultureInfo.InvariantCulture)));
                            }

                            this.items = navItems.AsReadOnly();
                        }
                        else
                        {
                            throw new DataException("Navigation group does not exist.");
                        }
                    }
                }
            }
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the navigation group's name.
        /// </summary>
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.name = value;
            }
        }

        /// <summary>
        /// Gets or sets the navigation group's intended location.
        /// </summary>
        public NavigationGroupArea Area
        {
            get
            {
                return this.area;
            }

            set
            {
                this.area = value;
            }
        }

        /// <summary>
        /// Gets the navigation group's contained navigation items.
        /// </summary>
        public IList<NavigationItem> Items
        {
            get
            {
                return this.items;
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Queries the database for a list of navigation groups in a certain template location for this application.
        /// </summary>
        /// <param name="area">The template location of the navigation groups.</param>
        /// <returns>A read-only list of navigation groups.</returns>
        public static IList<NavigationGroup> GetNavigationGroups(NavigationGroupArea area)
        {
            List<NavigationGroup> navs = new List<NavigationGroup>();
            using (SqlConnection conn = new SqlConnection(Environmental.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetNavGroups", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@NavItemArea", area);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                navs.Add(new NavigationGroup(rdr["NavItemGroup"].ToString(), area));
                            }
                        }
                    }
                }
            }

            return navs.AsReadOnly();
        }
        
        /// <summary>
        /// Inserts the HNavGroup object into the database.
        /// </summary>
        public void SaveAs()
        {
            using (SqlConnection conn = new SqlConnection(Environmental.ConnectionString))
            {
                conn.Open();
                for (int i = 0; i < this.items.Count; i++)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.InsertNavItem", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@NavItemLink", this.items[i].Link);
                        cmd.Parameters.AddWithValue("@NavItemText", this.items[i].Text);
                        cmd.Parameters.AddWithValue("@NavItemOrder", this.items[i].Ordinal);
                        cmd.Parameters.AddWithValue("@NavItemGroup", this.name);
                        cmd.Parameters.AddWithValue("@NavItemArea", this.area);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }

        /// <summary>
        /// Updates the HNavGroup's database entries.
        /// </summary>
        public void Save()
        {
            using (SqlConnection conn = new SqlConnection(Environmental.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.DeleteNavGroup", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@NavItemGroup", this.name);
                    cmd.Parameters.AddWithValue("@NavItemArea", this.area);
                    cmd.ExecuteNonQuery();
                }

                for (int i = 0; i < this.items.Count; i++)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.InsertNavItem", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@NavItemLink", this.items[i].Link);
                        cmd.Parameters.AddWithValue("@NavItemText", this.items[i].Text);
                        cmd.Parameters.AddWithValue("@NavItemOrder", this.items[i].Ordinal);
                        cmd.Parameters.AddWithValue("@NavItemGroup", this.name);
                        cmd.Parameters.AddWithValue("@NavItemArea", this.area);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }
        #endregion
    }
}